using Microsoft.AspNetCore.Http;
using System.Security.Claims;
using UniversalAdmin.Application.DTOs;
using UniversalAdmin.Application.Services;

namespace UniversalAdmin.Api.Middleware;

public class OperationLogMiddleware
{
    private readonly RequestDelegate _next;

    public OperationLogMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // 记录请求开始时间
        var startTime = DateTime.UtcNow;

        try
        {
            // 继续处理请求
            await _next(context);
        }
        finally
        {
            // 记录操作日志（不等待完成，避免影响响应速度）
            _ = LogOperationAsync(context, startTime);
        }
    }

    private async Task LogOperationAsync(HttpContext context, DateTime startTime)
    {
        try
        {
            // 跳过不需要记录日志的请求
            if (ShouldSkipLogging(context.Request.Path))
                return;

            // 获取用户信息
            var userIdClaim = context.User.FindFirst(ClaimTypes.NameIdentifier);
            var userNameClaim = context.User.FindFirst(ClaimTypes.Name);

            if (userIdClaim == null || !Guid.TryParse(userIdClaim.Value, out var userId))
                return;

            // 从服务提供器获取作用域服务
            var logService = context.RequestServices.GetRequiredService<IOperationLogService>();

            // 确定操作类型
            var operation = GetOperationType(context.Request.Method, context.Request.Path);

            // 获取操作描述
            var description = GetOperationDescription(context.Request.Method, context.Request.Path);

            // 获取客户端信息
            var ipAddress = GetClientIpAddress(context);
            var userAgent = context.Request.Headers["User-Agent"].FirstOrDefault();

            // 创建日志记录
            var logDto = new CreateOperationLogDto
            {
                UserId = userId,
                UserName = userNameClaim?.Value ?? "未知用户",
                Operation = operation,
                Description = description,
                IpAddress = ipAddress,
                UserAgent = userAgent
            };

            // 异步记录日志（不等待完成，避免影响响应速度）
            _ = Task.Run(async () =>
            {
                try
                {
                    await logService.CreateLogAsync(logDto);
                }
                catch
                {
                    // 日志记录失败不应影响主业务流程
                }
            });

            // 返回已完成的任务
            await Task.CompletedTask;
        }
        catch
        {
            // 日志记录过程中的异常不应影响主业务流程
        }
    }

    private bool ShouldSkipLogging(PathString path)
    {
        // 跳过不需要记录日志的路径
        var skipPaths = new[]
        {
            "/swagger",
            "/health",
            "/favicon.ico",
            "/api/v1/operationlog" // 避免日志记录本身产生日志
        };

        return skipPaths.Any(skipPath => path.StartsWithSegments(skipPath));
    }

    private string GetOperationType(string method, PathString path)
    {
        return method switch
        {
            "GET" => "查询",
            "POST" => "创建",
            "PUT" => "更新",
            "DELETE" => "删除",
            "PATCH" => "部分更新",
            _ => "其他"
        };
    }

    private string GetOperationDescription(string method, PathString path)
    {
        var pathSegments = path.Value?.Split('/', StringSplitOptions.RemoveEmptyEntries);
        if (pathSegments == null || pathSegments.Length < 3)
            return $"{method} {path}";

        var controller = pathSegments[2]; // api/v1/[controller]
        var action = method;

        if (pathSegments.Length > 3)
        {
            var idSegment = pathSegments[3];
            if (Guid.TryParse(idSegment, out _) || int.TryParse(idSegment, out _))
            {
                action = $"{method}ById";
            }
            else
            {
                action = idSegment;
            }
        }

        return $"{GetControllerDisplayName(controller)} - {GetActionDisplayName(action)}";
    }

    private string GetControllerDisplayName(string controller)
    {
        return controller.ToLower() switch
        {
            "user" => "用户管理",
            "role" => "角色管理",
            "menu" => "菜单管理",
            "article" => "文章管理",
            "articlecategory" => "文章分类",
            "systemconfig" => "系统配置",
            "operationlog" => "操作日志",
            "auth" => "认证管理",
            "personal" => "个人信息",
            _ => controller
        };
    }

    private string GetActionDisplayName(string action)
    {
        return action.ToLower() switch
        {
            "get" => "查询",
            "post" => "创建",
            "put" => "更新",
            "delete" => "删除",
            "login" => "登录",
            "logout" => "登出",
            "register" => "注册",
            "tree" => "获取树形结构",
            "status" => "更新状态",
            "view" => "更新浏览次数",
            "category" => "按分类查询",
            "author" => "按作者查询",
            "role" => "按角色查询",
            "daterange" => "按日期范围查询",
            _ => action
        };
    }

    private string GetClientIpAddress(HttpContext context)
    {
        // 尝试获取真实IP地址
        var forwardedHeader = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
        if (!string.IsNullOrEmpty(forwardedHeader))
        {
            return forwardedHeader.Split(',')[0].Trim();
        }

        var realIpHeader = context.Request.Headers["X-Real-IP"].FirstOrDefault();
        if (!string.IsNullOrEmpty(realIpHeader))
        {
            return realIpHeader;
        }

        return context.Connection.RemoteIpAddress?.ToString() ?? "未知";
    }
}